<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input
        v-model="listQuery.name"
        placeholder="名称"
        style="width: 200px"
        class="filter-item"
        maxlength="50"
        show-word-limit
        @keyup.enter.native="handleFilter"
      />
      <el-input
        v-model="listQuery.fileName"
        placeholder="文件名称"
        maxlength="200"
        show-word-limit
        style="width: 200px"
        class="filter-item"
        @keyup.enter.native="handleFilter"
      />
      <el-select
        v-model="listQuery.type"
        placeholder="类型"
        clearable
        style="width: 90px"
        class="filter-item"
      >
        <el-option
          v-for="item in pluginTypeOptions"
          :key="item.key"
          :label="item.display_name"
          :value="item.key"
        />
      </el-select>
      <el-button
        class="filter-item"
        type="primary"
        icon="el-icon-search"
        @click="handleFilter"
      >
        搜索
      </el-button>
      <el-button
        class="filter-item"
        style="margin-left: 10px"
        type="primary"
        icon="el-icon-edit"
        @click="handleCreate"
      >
        添加解析器
      </el-button>
      <el-button
        :loading="downloadLoading"
        class="filter-item"
        type="primary"
        icon="el-icon-link"
        @click="handleSync"
      >
        同步
      </el-button>
    </div>

    <el-table
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row
      style="width: 100%"
    >
      <el-table-column label="序号" type="index" align="center" width="50">
      </el-table-column>
      <el-table-column
        label="名称"
        min-width="10%"
        align="center"
        show-overflow-tooltip
      >
        <template slot-scope="{ row }">
          <span>{{ row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column label="类型" min-width="5%" align="center">
        <template slot-scope="{ row }">
          <span>{{ row.type }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="文件名称"
        min-width="10%"
        align="center"
        show-overflow-tooltip
      >
        <template slot-scope="{ row }">
          <span>{{ row.fileName }}</span>
        </template>
      </el-table-column>
      <el-table-column label="文件大小(MB)" min-width="5%" align="center">
        <template slot-scope="{ row }">
          <span>{{ (row.fileVolumn / 1024).toFixed(2) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" min-width="10%" align="center">
        <template slot-scope="{ row }">
          <span>{{ row.createTime }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        align="center"
        min-width="10%"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="{ row }">
          <el-button size="mini" @click="handleDownload(row.uuid)">
            下载
          </el-button>
          <el-button size="mini" @click="handleUpdate(row)"> 编辑 </el-button>
          <el-button
            v-if="row.status != 'deleted'"
            size="mini"
            type="danger"
            @click="handlePluginDelete(row.uuid)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="listQuery.page"
      :limit.sync="listQuery.limit"
      @pagination="getList"
    />
    <el-dialog
      :visible.sync="dialogTableVisible"
      title="同步执行器"
      @dragDialog="handleSync"
      ><div class="filter-container">
        <el-button :loading="asyncAllLoading" @click="asyncAllPlugin()"
          >全部同步</el-button
        >
      </div>
      <el-table
        :key="tableKey"
        v-loading="listExecutorLoading"
        :data="executorlist"
        border
        fit
        highlight-current-row
        style="width: 100%"
      >
        <el-table-column label="序号" type="index" align="center" width="50">
        </el-table-column>
        <el-table-column
          label="名称"
          min-width="10%"
          align="center"
          show-overflow-tooltip
        >
          <template slot-scope="{ row }">
            <span>{{ row.title }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="AppName"
          min-width="10%"
          align="center"
          show-overflow-tooltip
        >
          <template slot-scope="{ row }">
            <span>{{ row.appname }}</span>
          </template>
        </el-table-column>
        <el-table-column label="类型" min-width="5%" align="center">
          <template slot-scope="{ row }">
            <span>{{ typeMap[row.addressType] }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="地址"
          min-width="10%"
          align="center"
          show-overflow-tooltip
        >
          <template slot-scope="{ row }">
            <span>{{ row.addressList }}</span>
          </template>
        </el-table-column>
        <el-table-column label="同步结果" min-width="10%" align="center">
          <template slot-scope="scope">
            <i
              class="el-icon-success"
              v-show="asyncResult != null && asyncResult[scope.$index] == 3"
            ></i>
            <i
              class="el-icon-error"
              v-show="asyncResult != null && asyncResult[scope.$index] == 2"
              >失败</i
            >
            <i
              class="el-icon-loading"
              v-show="asyncResult != null && asyncResult[scope.$index] == 1"
            ></i>
            <el-button
              type="primary"
              icon="el-icon-refresh-right"
              v-show="asyncResult[scope.$index] == 0"
              @click="asyncPlugin(scope.$index, scope.row.id)"
            ></el-button>
            <el-button
              type="warning"
              icon="el-icon-tickets"
              v-show="asyncResult[scope.$index] == 2"
              @click="showAsyncLog(scope.$index)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
      <el-form
        ref="dataForm"
        :rules="rules"
        :model="tempData"
        label-position="left"
        label-width="70px"
        style="width: 400px; margin-left: 50px"
      >
        <el-form-item prop="uuid" v-show="false">
          <el-input v-model="tempData.uuid" />
        </el-form-item>
        <el-form-item prop="name" label="名称">
          <el-input
            v-model="tempData.name"
            maxlength="50"
            show-word-limit
            placeholder="解析器名称"
          />
        </el-form-item>
        <el-form-item prop="type" label="类型">
          <el-select
            class="filter-item"
            v-model="tempData.type"
            placeholder="请选择解析器类型"
            :disabled="dialogStatus === 'update'"
          >
            <el-option
              v-for="item in pluginTypeOptions"
              :key="item.key"
              :label="item.display_name"
              :value="item.key"
            />
          </el-select>
        </el-form-item>
        <el-form-item prop="file" v-show="dialogStatus === 'create'">
          <el-upload
            v-model="tempData.file"
            drag
            :auto-upload="false"
            action="/"
            :file-list="dialogStatus === 'create' ? fileList : uploadedFileList"
            :http-request="selectFile"
            :on-change="handleFileChange"
            :on-remove="handleFileRemove"
            :on-success="handleFileSucess"
            accept=".zip"
            ref="uploadFile"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">
              将文件拖到此处，或<em>点击上传</em>
            </div>
            <div class="el-upload__tip" slot="tip">
              只能上传zip文件，且不超过100MB
            </div>
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="close"> 取消 </el-button>
        <el-button
          type="primary"
          :loading="createButtonLoading"
          @click="dialogStatus === 'create' ? createData() : updateData()"
        >
          确认
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import {
  listPlugin,
  addPlugin,
  deletePlugin,
  updatePlugin,
  downloadPluginFile,
  asyncPlugin,
} from "@/api/plugin";
import { listExecutor } from "@/api/executor";
const pluginTypeOptions = [
  { key: "reader", display_name: "reader" },
  { key: "writer", display_name: "writer" },
];

export default {
  components: { Pagination },
  data() {
    return {
      tableKey: 0,
      //列表总数
      total: 0,
      //解析器列表加载标识位
      listLoading: true,
      //解析器列表
      list: [],
      //解析器查询参数
      listQuery: {
        page: 1,
        limit: 20,
        name: undefined,
        type: undefined,
        fileName: undefined,
      },
      //解析器类型选项
      pluginTypeOptions,
      formData: "",
      //解析器添加和编辑对话框数据
      tempData: {},
      fileList: [],
      uploadedFileList: [],
      dialogFormVisible: false,
      dialogStatus: "",
      textMap: {
        update: "编辑",
        create: "添加",
      },
      createButtonLoading: false,
      rules: {
        type: [
          { required: true, message: "请选择解析器类型", trigger: "change" },
        ],
        name: [
          { required: true, message: "请输入解析器名称", trigger: "change" },
        ],
      },
      downloadLoading: false,
      dialogTableVisible: false,
      listExecutorLoading: false,
      executorlist: [],
      executorTotal: 0,
      listExecutorQuery: {
        page: 1,
        limit: 999,
        appname: undefined,
        title: undefined,
      },
      typeMap: ["自动注册", "手动注册"],
      statusMap: ["失效", "正常"],
      asyncResult: [],
      asyncLog: [],
      asyncAllLoading: false,
    };
  },
  created() {
    this.getList();
    this.getExecutorlist();
  },
  methods: {
    //获取列表
    async getList() {
      this.listLoading = true;
      const data = await listPlugin(this.listQuery).then((response) => {
        return response.data;
      });
      this.list = data.list;
      this.total = data.total;
      let maxPage = Math.ceil(this.total / this.listQuery.limit);
      if (this.listQuery.page > maxPage) {
        this.listQuery.page = maxPage;
        this.getList();
      }
      setTimeout(() => {
        this.listLoading = false;
      }, 1 * 1000);
    },
    //执行器获取列表
    async getExecutorlist() {
      this.listExecutorLoading = true;
      const data = await listExecutor(this.listExecutorQuery).then(
        (response) => {
          return response.data;
        }
      );
      if (data.total > 999) {
        this.listExecutorQuery.limit = data.total;
        data = await listExecutor(this.listExecutorQuery).then((response) => {
          return response.data;
        });
      }
      this.executorlist = data.list;
      this.executorTotal = data.total;
      this.asyncResult = new Array(data.total);

      for (var i = 0; i < data.total; i++) {
        this.asyncResult[i] = 0;
        this.asyncLog[i] = "";
      }
      setTimeout(() => {
        this.listExecutorLoading = false;
      }, 1 * 1000);
    },
    //选择文件
    selectFile(file) {
      this.formData.append("file", file.file);
    },
    //选择文件发生变化
    handleFileChange(file) {
      this.fileList = [];
      this.fileList.push(file);
      this.uploadedFileList = [];
      this.uploadedFileList.push(file);
    },
    //选择文件发生变化
    handleFileRemove(file) {
      //this.fileList = [];
    },
    //选择文件成功
    handleFileSucess() {},
    //搜索
    handleFilter() {
      this.listQuery.page = 1;
      this.getList();
    },
    //弹出添加框
    handleCreate() {
      this.resetTemp();
      this.dialogStatus = "create";
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    //添加解析器
    createData() {
      if (this.fileList.length == 0) {
        this.$notify({
          message: "未上传文件",
          type: "error",
          duration: 2000,
        });
        return;
      }
      this.$refs["dataForm"].validate((valid) => {
        if (valid) {
          this.createButtonLoading = true;
          let formData = new FormData();
          formData.append("name", this.tempData.name);
          formData.append("type", this.tempData.type);
          formData.append("file", this.fileList[0].raw);
          addPlugin(formData).then((response) => {
            if (response) {
              this.$notify({
                message: "添加成功",
                type: "success",
                duration: 2000,
              });
              this.close();
              this.getList();
            } else {
              this.$notify({
                message: "添加失败",
                type: "error",
                duration: 2000,
              });
            }
          });
          this.createButtonLoading = false;
        }
      });
    },
    //更新解析器
    async updateData() {
      if (this.fileList.length == 0 && this.uploadedFileList.length == 0) {
        this.$notify({
          message: "未上传文件",
          type: "error",
          duration: 2000,
        });
        return;
      }
      this.$refs["dataForm"].validate((valid) => {
        if (valid) {
          let formData = new FormData();
          formData.append("name", this.tempData.name);
          formData.append("type", this.tempData.type);
          formData.append("uuid", this.tempData.uuid);
          updatePlugin(formData).then((response) => {
            if (response) {
              this.$notify({
                message: "更新成功",
                type: "success",
                duration: 2000,
              });
              this.close();
              this.getList();
            }
          });
        }
      });
    },
    //关闭对话框
    close() {
      this.dialogFormVisible = false;
      this.$refs["uploadFile"].clearFiles();
      this.resetTemp();
    },
    //初始化对话框
    resetTemp() {
      this.createButtonLoading = false;
      this.fileList = [];
      this.uploadedFileList = [];
      this.tempData = {
        uuid: undefined,
        name: undefined,
        type: undefined,
        file: undefined,
      };
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    handleUpdate(row) {
      this.resetTemp();
      this.tempData = Object.assign({}, row);
      this.dialogStatus = "update";
      let file = {
        name: row.fileName,
      };
      this.uploadedFileList.push(file);
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    //删除解析器
    async handlePluginDelete(uuid) {
      const confirmRes = await this.$confirm(
        "此操作将永久删除该数据, 是否继续?",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).catch((err) => console.log(err));
      if (confirmRes == "confirm") {
        this.listLoading = true;
        let uuids = [];
        uuids.push(uuid);
        let response = await deletePlugin(uuids);
        if (response) {
          this.$notify({
            message: "删除成功",
            type: "success",
            duration: 2000,
          });
        } else {
          this.$notify({
            message: "删除失败",
            type: "error",
            duration: 2000,
          });
        }
        this.getList();
      }
    },
    //同步解析器
    async handleSync() {
      this.getExecutorlist();
      this.dialogTableVisible = true;
    },

    //下载解析器文件
    async handleDownload(uuid) {
      downloadPluginFile(uuid);
    },

    async asyncPlugin(index, executorId) {
      this.asyncResult.splice(index, 1, 1);
      let response = await asyncPlugin({ id: executorId });
      this.asyncLog[index] = response.data;

      setTimeout(() => {
        if (response.data == null || response.data.length == 0) {
          this.asyncResult.splice(index, 1, 3);
        } else {
          this.asyncResult.splice(index, 1, 2);
        }
      }, 1 * 1000);
    },
    async showAsyncLog(index) {
      this.$alert(this.asyncLog[index], "日志", {});
    },
    async asyncAllPlugin() {
      this.asyncAllLoading = true;
      for (var i = 0; i < this.executorlist.length; i++) {
        const executorId = this.executorlist[i].id;
        await this.asyncPlugin(i, executorId);
      }
      setTimeout(() => {
        this.asyncAllLoading = false;
      }, 2 * 1000);
    },
  },
};
</script>
